﻿using UnityEngine;
using System;
using System.Collections.Generic;
using BitBenderGames;
using DG.Tweening;
using TMPro;
using Yoozoo.Framework.Core;
using WorldMap;
using WorldMapBase.Camera;
using Yoozoo.Core.Common;
using Yoozoo.Gameplay.RTS;
using Yoozoo.HRP.Runtime;

public class WorldCameraManager : SingletonMono<WorldCameraManager>, ICamera
{
    public const float CAMERA_HEIGHT_CHECK = 0.01f;
    public const float CAMERA_FOV_CHECK = 0.005f;

    public class MyOptions : Options
    {
        public string cameraTag = "WorldCamera";
        public bool IsNew = true;
    }
    public static event Action<Vector2> moveEventHandler;
    public static event Action<float> scaleEventHandler;
    public static event Action<Vector3> moveEvent3DHandler;

    public static event Action<Vector2> luaMoveEventHandler;
    
    public static event Action<Vector2> luaMoveEndEventHandler;
    public static Camera mainCamera { get; set; }

    public static HCamera hMainCamera { get; set; }
    
    public  Vector2 CenterViewPosition { get; private set; }
    private Vector2 m_LastCenterViewPosition { get;  set; }
    
    public Vector3[] m_CornersPosition = new Vector3[4];

    private float cameraZOffsetCache = 0;

    public static TouchCameraController cameraController { get; private set; }

    private static CameraMoveComponent cameraMoveComponent;

    public float BaseDistance { get; private set; }

    public float CameraFOV { get; private set; }
    private float _maxWidth;
    public float MaxWidth
    {
        get
        {
            return _maxWidth;
        }
        private set
        {
            _maxWidth = value;
            _halfW = value / 2;
        }
    }

    private float _maxHeight;
    public float MaxHeight
    {
        get
        {
            return _maxHeight;
        }
        private set
        {
            _maxHeight = value;
            _halfH = _maxHeight/2;
        } 
    }

    private float _halfW;
    private float _halfH;
    public static Vector3 MinOffset = new Vector3(0,14.142f,0);

    private MyOptions m_options;
    private Vector3 m_CenterPos;

    //private Vector3 initCameraPos = new Vector3(163.0f, 130f, 218f);
    

    private static Dictionary<string,GameObject> cameraObjs = new Dictionary<string,GameObject>();
    private static GameObject currentCameraObject;

    private bool isCameraMoving = false;

    public void SetCamera(Camera camera)
    {
        mainCamera = camera;
        if (camera != null)
        {
            mobileTouchCamera = camera.gameObject.GetComponentInChildren<MobileTouchCamera>();
            cameraController = camera.gameObject.GetComponentInChildren<TouchCameraController>();
            cameraMoveComponent = cameraController.gameObject.GetComponentInChildren<CameraMoveComponent>();
            //UnityEngine.Debug.LogError("[WorldCameraManager]SetCamera() -> cameraController", cameraController);
            //UnityEngine.Debug.LogError("[WorldCameraManager]SetCamera() -> cameraMoveComponent", cameraMoveComponent);
        }
    }
    
    public  Camera GetCamera()
    {
        return mainCamera;
    }
    public override void Initialize(Options options = null)
    {


        m_options = options == null ? new MyOptions() : options as MyOptions;

        var cameraObject = GameObject.FindWithTag(m_options.cameraTag);
        mainCamera = cameraObject.GetComponent<Camera>();
        hMainCamera = cameraObject.GetComponent<HCamera>();
        //放到进入沙盘以后再启用
        HCameraManager.DisableCamera(hMainCamera);
        //禁用hudcamera
        var hudCamera = cameraObject.transform.Find("HudCamera");
        if (hudCamera != null)
        {
            var hHudCamera = hudCamera.gameObject.GetComponent<HCamera>();
            if (hHudCamera)
            {
                HCameraManager.DisableCamera(hHudCamera);
            }
        }
       
        mainCamera.depthTextureMode = DepthTextureMode.Depth;


        cameraController = mainCamera.transform.GetComponent<TouchCameraController>();
        cameraMoveComponent = cameraController.gameObject.GetComponentInChildren<CameraMoveComponent>();
        //UnityEngine.Debug.LogError("[WorldCameraManager]Initialize() -> cameraController", cameraController);
        //UnityEngine.Debug.LogError("[WorldCameraManager]Initialize() -> cameraMoveComponent", cameraMoveComponent);

        mobileTouchCamera = mainCamera.transform.GetComponent<MobileTouchCamera>();
        
        
        FindGroundViewCorner();
        base.Initialize(options);
    }

    public override void Dispose()
    {
        QualityHelper.ChangeInteractingState(false);
        ElementManager.shakeEnabled = true;
        HCameraManager.DisableCamera(hMainCamera);
        mainCamera = null;
        hMainCamera = null;
        moveEventHandler = null;
        scaleEventHandler = null;
        cameraController = null;
        cameraMoveComponent = null;
        //UnityEngine.Debug.LogError("[WorldCameraManager]cameraController = null");

        base.Dispose();
    }


    public bool m_isScreenUpdate = false;

    public bool ShowViewGrid = false;
    
    public void OnUpdate()
    {
        if(m_isScreenUpdate)
        {
            RTSScreenUpdate();
        }
    }


    private void RTSScreenUpdate()
    {
        var transform = mainCamera.transform;
        FindGroundViewCorner();
        // 摄像机y轴会选择45度 所以现在中心点是等腰梯形中心点
        Vector3 point0 = (m_CornersPosition[0] + m_CornersPosition[1]) * 0.5f;
        Vector3 point1 = (m_CornersPosition[2] + m_CornersPosition[3]) * 0.5f;
        Vector3 targetPosition = (point0 + point1) * 0.5f;
        targetPosition.y = 0;
        
#if UNITY_EDITOR
        Debug.DrawLine(mainCamera.transform.position, targetPosition, Color.yellow, 0, false);
#endif
        
        var currentPosition = new Vector2(targetPosition.x, targetPosition.z);
        UpdateCenterViewPosition(currentPosition);
        m_LastCenterViewPosition = CenterViewPosition;
    }

    public Vector2 GetLastCenterViewPosition()
    {
        return m_LastCenterViewPosition;
    }

    public void UpdateCenterViewPosition(Vector2 currentPosition)
    {
        Vector3 targetPosition = new Vector3(currentPosition.x, 0, currentPosition.y);
        bool isCameraMoving = false;
        if (currentPosition != CenterViewPosition)
        {
            //Debug.LogError( "更新视野位置：" + currentPosition.ToString());
            luaMoveEventHandler?.Invoke(currentPosition);
            isCameraMoving = true;
        }
        else
        {
            isCameraMoving = false;
        }

        if (isCameraMoving != this.isCameraMoving)
        {
            if (this.isCameraMoving && !isCameraMoving)
            {
                luaMoveEndEventHandler?.Invoke(currentPosition);
            }
            QualityHelper.ChangeInteractingState(isCameraMoving);
            ElementManager.shakeEnabled = !isCameraMoving;
            this.isCameraMoving = isCameraMoving;
        }
        CenterViewPosition = currentPosition;


        if (Vector2.Distance(CenterViewPosition, currentPosition) > 5)
        {
            moveEventHandler?.Invoke(currentPosition);
            moveEvent3DHandler?.Invoke(targetPosition);
            Debug.DrawLine(new Vector3(CenterViewPosition.x, 0, CenterViewPosition.y), targetPosition, Color.green);
        }
        else
        {
            Debug.DrawLine(new Vector3(CenterViewPosition.x, 0, CenterViewPosition.y), targetPosition, Color.green);
        }

        if (Mathf.Abs(mainCamera.fieldOfView - CameraFOV) > CAMERA_FOV_CHECK)
        {
            CameraFOV = mainCamera.fieldOfView;
        }

        if (Mathf.Abs(mainCamera.transform.position.y - BaseDistance) > CAMERA_HEIGHT_CHECK || BaseDistance <= 0.0f)
        {
            BaseDistance = mainCamera.transform.position.y;
            scaleEventHandler?.Invoke(BaseDistance);
        }
        else
        {
            Debug.DrawLine(new Vector3(CenterViewPosition.x, 0, CenterViewPosition.y), targetPosition, Color.green);
        }
        Debug.DrawLine(mainCamera.transform.position, CenterViewPosition, Color.white);
    }
    private void FindGroundViewCorner()
    {
        Vector3[] planeConrners = GetCorners(mainCamera.nearClipPlane);
        Vector3 pos = mainCamera.transform.position;
        m_CornersPosition[0] = WorldMapUtility.GetIntersectionWithLineAndPlane(pos, pos - planeConrners[0],
            Vector3.up, Vector3.zero);
        m_CornersPosition[1] = WorldMapUtility.GetIntersectionWithLineAndPlane(pos, pos - planeConrners[1],
            Vector3.up, Vector3.zero);
        m_CornersPosition[2] = WorldMapUtility.GetIntersectionWithLineAndPlane(pos, pos - planeConrners[2],
            Vector3.up, Vector3.zero);
        m_CornersPosition[3] = WorldMapUtility.GetIntersectionWithLineAndPlane(pos, pos - planeConrners[3],
            Vector3.up, Vector3.zero);

        float tempMaxHeight = Mathf.Abs(m_CornersPosition[0].z - m_CornersPosition[2].z);
        float tempMaxWidth = Mathf.Abs(m_CornersPosition[0].x - m_CornersPosition[1].x);
        if (tempMaxHeight != MaxHeight || tempMaxWidth != MaxWidth)
        {
            //最大宽高改变，通知外部
            MaxHeight = tempMaxHeight * 1.4f;
            MaxWidth = tempMaxWidth * 2f;
            DrawLineTool.GetInstance().SetWHRect(MaxWidth,MaxHeight,mobileTouchCamera.TouchCameraController.LOD1);
        }
        // Debug.LogWarning($"MaxHeight:{MaxHeight} MaxWidth:{MaxWidth}");
        //
        //

        #if UNITY_EDITOR
        Color color = Color.magenta;
        Debug.DrawLine(m_CornersPosition[0], m_CornersPosition[1], color,0,false);
        Debug.DrawLine(m_CornersPosition[1], m_CornersPosition[3], color,0,false);
        Debug.DrawLine(m_CornersPosition[0], m_CornersPosition[2], color,0,false);
        Debug.DrawLine(m_CornersPosition[2], m_CornersPosition[3], color,0,false);

        // // 经过放大后的较为正确的视野范围
        // float xMin = CenterViewPosition.x - _halfW;
        // float xMax = CenterViewPosition.x + _halfW;
        // float yMin = CenterViewPosition.y - _halfH;
        // float yMax = CenterViewPosition.y + _halfH;
        // Debug.DrawLine(new Vector3(xMin,0,yMin),new Vector3(xMax,0,yMin),Color.red,0,false);
        // Debug.DrawLine(new Vector3(xMax,0,yMin),new Vector3(xMax,0,yMax),Color.red,0,false);
        // Debug.DrawLine(new Vector3(xMax,0,yMax),new Vector3(xMin,0,yMax),Color.red,0,false);
        // Debug.DrawLine(new Vector3(xMin,0,yMax),new Vector3(xMin,0,yMin),Color.red,0,false);

        float mapSize = WorldEntry.m_mapSize;
        
        Debug.DrawLine(Vector3.zero, new Vector3(mapSize,0,0), color, 0, false);
        Debug.DrawLine(new Vector3(mapSize, 0, 0), new Vector3(mapSize, 0, mapSize), color, 0, false);
        Debug.DrawLine(new Vector3(mapSize, 0, mapSize), new Vector3(0, 0, mapSize), color, 0, false);
        Debug.DrawLine(new Vector3(0, 0, mapSize), Vector3.zero, color, 0, false);
        #endif
        
        DrawServerViewRect();
        DrawClientEditorViewRect();
        //
        // var a = m_CornersPosition[2] - m_CornersPosition[0];
        // var b = m_CornersPosition[2] - m_CornersPosition[3];
        // var p = Vector3.Project(a, b);
        //
        // Debug.DrawLine(m_CornersPosition[2], m_CornersPosition[2]+p, Color.yellow);
        //
        // Debug.LogWarning($"Width:{Vector3.Distance(m_CornersPosition[2],m_CornersPosition[3])}");
        // // Debug.LogWarning($"Width:{Mathf.Abs(m_CornersPosition[2].x - m_CornersPosition[3].x)}");
        // Debug.LogWarning($"Height:{DistanceOfPointToVector(m_CornersPosition[2],m_CornersPosition[3],m_CornersPosition[0])}");
    }

    /// <summary>
    /// 求点到直线的距离，采用数学公式Ax+By+C = 0; d = A*p.x + B * p.y + C / sqrt(A^2 + B ^ 2)
    /// 此算法忽略掉三维向量的Y轴，只在XZ平面进行计算，适用于一般3D游戏。
    /// </summary>
    /// <param name="startPoint">向量起点</param>
    /// <param name="endPoint">向量终点</param>
    /// <param name="point">待求距离的点</param>
    /// <returns></returns>
    public static float DistanceOfPointToVector(Vector3 startPoint, Vector3 endPoint, Vector3 point)
    {
        Vector2 startVe2 = startPoint.xz();
        Vector2 endVe2 = endPoint.xz();
        float A = endVe2.y - startVe2.y;
        float B = startVe2.x - endVe2.x;
        float C = endVe2.x * startVe2.y - startVe2.x * endVe2.y;
        float denominator = Mathf.Sqrt(A * A + B * B);
        Vector2 pointVe2 = point.xz();
        return Mathf.Abs((A * pointVe2.x + B * pointVe2.y + C) / denominator);;
    }



    private Vector3[] corners = new Vector3[4];
    [NonSerialized]
    public MobileTouchCamera mobileTouchCamera;

    private Vector3[] GetCorners(float distance)
    {
        //Vector3[] corners = new Vector3[4];

        float halfFOV = (mainCamera.fieldOfView * 0.5f) * Mathf.Deg2Rad;
        float aspect = mainCamera.aspect;

        float height = distance * Mathf.Tan(halfFOV);
        float width = height * aspect;

        // UpperLeft
        corners[0] = mainCamera.transform.position - (mainCamera.transform.right * width);
        corners[0] += mainCamera.transform.up * height;
        corners[0] += mainCamera.transform.forward * distance;

        // UpperRight
        corners[1] = mainCamera.transform.position + (mainCamera.transform.right * width);
        corners[1] += mainCamera.transform.up * height;
        corners[1] += mainCamera.transform.forward * distance;

        // LowerLeft
        corners[2] = mainCamera.transform.position - (mainCamera.transform.right * width);
        corners[2] -= mainCamera.transform.up * height;
        corners[2] += mainCamera.transform.forward * distance;

        // LowerRight
        corners[3] = mainCamera.transform.position + (mainCamera.transform.right * width);
        corners[3] -= mainCamera.transform.up * height;
        corners[3] += mainCamera.transform.forward * distance;
        
        // 这个corners的计算是错误的，后续再修改吧
        // Debug.DrawLine(corners[0], corners[1], Color.blue,0,false);
        // Debug.DrawLine(corners[1], corners[2], Color.blue,0,false);
        // Debug.DrawLine(corners[2], corners[3], Color.blue,0,false);
        // Debug.DrawLine(corners[3], corners[0], Color.blue,0,false);


        return corners;
    }

    public void SetTileSize(int tileWidth, int tileHeight,int XNum)
    {

    }

    float GetCameraZOffset()
    {
        if (!cameraZOffsetCache.Equals(0))
        {
            return cameraZOffsetCache;
        }
        if (mainCamera.gameObject == null)
        {
            return 0;
        }
        cameraZOffsetCache = mainCamera.transform.position.y / Mathf.Tan(mainCamera.transform.localRotation.eulerAngles.x * Mathf.Deg2Rad);
        return cameraZOffsetCache;
    }

    /// <summary>
    /// 设置相机焦点可以移动的范围
    /// </summary>
    /// <param name="o">矩形最小点</param>
    /// <param name="size">矩形宽高</param>
    public void SetBoundary(Vector2 o,Vector2 size)
    {
        cameraController.SetCameraBoundary(new Rect(o,size));
    }

    /// <summary>
    /// 看向地图平面某个点，点必须是 0 高度平面
    /// </summary>
    /// <param name="pos">看向的目标点</param>
    /// <param name="duration">相机飞行时间</param>
    /// <param name="ease">飞行缓动方式</param>
    /// <param name="callback">飞行完成的回调</param>
    /// <param name="zoom">飞行到目标点后摄像机距离的目标值，一旦大于0,则平滑移动过去</param>
    public static void FocusTo(Vector2 pos,float duration,Ease ease = Ease.Linear,TweenCallback callback = null,float zoom = -1)
    {
        //UnityEngine.Debug.LogError("[WorldCameraManager]FocusTo()", cameraMoveComponent);
        cameraMoveComponent.TweenFocusAt(pos,duration,ease,zoom,callback);
    }

    public static void FocusToByTime(Vector2 pos, float duration, Ease ease = Ease.Linear, TweenCallback callback = null, float zoom = -1)
    {
        //UnityEngine.Debug.LogError("[WorldCameraManager]FocusToByTime()", cameraMoveComponent);
        cameraMoveComponent.TweenFocusAtByTime(pos, duration, ease, zoom, callback);
    }

    public static void MoveTo(Vector2 pos)
    {
        //UnityEngine.Debug.LogError("[WorldCameraManager]MoveTo()", cameraMoveComponent);
        cameraMoveComponent.ChangePos(pos);
    }

    public static void ChangPosToViewCenter(Vector2 pos)
    {
        //UnityEngine.Debug.LogError("[WorldCameraManager]ChangPosToViewCenter()", cameraMoveComponent);
        cameraMoveComponent.ChangPosToViewCenter(pos);
    }


    public static void ZoomFOVImmediately(float percent)
    {
        //UnityEngine.Debug.LogError("[WorldCameraManager]ZoomFOVImmediately()", cameraMoveComponent);
        cameraMoveComponent.ZoomFOVImmediately(percent);
    }

    public static void SetFOVImmediately(float percent)
    {
        //UnityEngine.Debug.LogError("[WorldCameraManager]SetFOVImmediately()", cameraMoveComponent);
        cameraMoveComponent.SetFOVImmediately(percent);
    }

    public static void ZoomLOD(int lodLayer,float percent,float duration,Ease ease = Ease.Linear,TweenCallback callback = null)
    {
        //UnityEngine.Debug.LogError("[WorldCameraManager]ZoomLOD()", cameraMoveComponent);
        cameraMoveComponent.ZoomLOD(lodLayer,percent,duration,ease,callback);
    }

    public static void SetLOD0MinPercent(float minPercent)
    {
        cameraController.SetLOD0MinPercent(minPercent);
    }

    public static void SetLOD0MaxPercent(float minPercent)
    {
        cameraController.SetLOD0MaxPercent(minPercent);
    }

    /// <summary>
    /// 调整相机和目标点距离（缩放距离）
    /// </summary>
    /// <param name="zoom">目标距离</param>
    /// <param name="duration">缩放过程时长（速度）</param>
    /// <param name="ease">相机飞行缓动方式</param>
    /// <param name="callback">相机飞行完成的回调</param>
    public static void ZoomTo(float zoom,float duration,Ease ease = Ease.Linear,TweenCallback callback = null)
    {
        //UnityEngine.Debug.LogError("[WorldCameraManager]ZoomTo()", cameraMoveComponent);
        cameraMoveComponent.ZoomTo(zoom,duration,ease,callback);
    }

    public static void ShowBound(Vector4 bound,Vector4 uiBound,float duration,Ease ease = Ease.Linear,TweenCallback callback = null,float zoom = -1)
    {
 
        
        Vector4 cameraBound = GetInstance().GetCameraCorner();

        
        GameObject rootCanvasGo = GameObject.Find("RootCanvas");
        if (rootCanvasGo != null)
        {
            float scaleFactor = rootCanvasGo.GetComponent<Canvas>().scaleFactor;

            cameraBound.x += (cameraBound.z - cameraBound.x) * (uiBound.x * scaleFactor / Screen.width);
            cameraBound.z -= (cameraBound.z - cameraBound.x) * (uiBound.y * scaleFactor / Screen.width);

            cameraBound.y += (cameraBound.w - cameraBound.y) * (uiBound.w * scaleFactor / Screen.height);
            cameraBound.w -= (cameraBound.w - cameraBound.y) * (uiBound.z * scaleFactor / Screen.height);

        }
        
        float minX = cameraBound.x - bound.x;    // > 0 
        float maxX = cameraBound.z - bound.z;    // < 0

        float minY = cameraBound.y - bound.y;    // > 0
        float maxY = cameraBound.w - bound.w;    // < 0

        if (minX <= 0 && maxX >= 0 && minY <= 0 && maxY >= 0)
        {
            return;
        }
        
        if (minX > 0 && maxX < 0)
        {
            return;    // 左右都超了 就不跳转了
        }

        if (minY > 0 && maxY < 0)
        {
            return;
        }

        float offsetX = 0;
        if (minX > 0) {
            offsetX = -minX;
        }

        if (maxX < 0) {
            offsetX = -maxX;
        }

        float offsetY = 0;
        if (minY > 0) {
            offsetY = -minY;
        }

        if (maxY < 0) {
            offsetY = -maxY;
        }

        Vector3 target = cameraController.Camera.transform.position;
        target.x += offsetX;
        target.z += offsetY;
        
        cameraController.SetCameraLockStatus(true);
        cameraController.CameraTransform.DOMove(target, duration).SetEase(ease).OnComplete(() =>
        {
            cameraController.SetCameraLockStatus(false);
            callback?.Invoke();
        });
    }
    
    public static void SetMinDistance(float value)
    {
        var trans = mainCamera.transform;
        Vector3 position = trans.position;
        float rad = trans.localEulerAngles.x * Mathf.Deg2Rad;
        float offsetZ = (value - position.y) / Mathf.Tan(rad);
        MinOffset = new Vector3(position.x,value,position.z-offsetZ);
    }

    public static void AddLuaMoveEventHandler(Action<Vector2> action)
    {
        luaMoveEventHandler += action;
    }

    public static void RemoveLuaMoveEventHandler(Action<Vector2> action)
    {
        luaMoveEventHandler -= action;
    }
    
    public static void AddLuaMoveEndEventHandler(Action<Vector2> action)
    {
        luaMoveEndEventHandler += action;
    }

    public static void RemoveLuaMoveEndEventHandler(Action<Vector2> action)
    {
        luaMoveEndEventHandler -= action;
    }

    public Vector4 GetCameraCorner()
    {
        Vector4 vec4 = new Vector4();

        vec4.x = CenterViewPosition.x - _halfW;
        vec4.y = CenterViewPosition.y - _halfH;
        vec4.z = CenterViewPosition.x + _halfW;
        vec4.w = CenterViewPosition.y + _halfH;

        return vec4;
    }

    public bool InCamera(Vector3 position)
    {
        if (position.x < CenterViewPosition.x - _halfW)
            return false;
        if (position.x > CenterViewPosition.x + _halfW)
            return false;
        if (position.z < CenterViewPosition.y - _halfH)
            return false;
        if (position.z > CenterViewPosition.y + _halfH)
            return false;
        return true;
    }

    public float GetCameraHeight()
    {
        return BaseDistance;
    }

    public float GetCameraFOV()
    {
        return cameraController.Camera.fieldOfView;
    }

    public Vector2 GetCameraCenter()
    {
        return CenterViewPosition;
    }

    public bool IsOnUI()
    {
        return BitBenderGames.TouchInputController.mLastOnUi;
    }

    private float serverViewCenterX;
    private float serverViewCenterY;
    private float serverViewRectWidth;
    private float serverViewRectHeight;
    private int serverViewGridWidth = 4;
    private int serverViewGridHeight = 2;
    private float serverViewRectAngle;
    
    public void SetServerViewRect(float centerX, float centerY, float width, float height, int gridWidth,int gridHeight,float angle)
    {
        serverViewCenterX = centerX;
        serverViewCenterY = centerY;
        serverViewRectWidth = width;
        serverViewRectHeight = height;
        serverViewRectAngle = angle;
        serverViewGridWidth = gridWidth;
        serverViewGridHeight = gridHeight;
    }

    private float serverViewLeft;
    private float serverViewRight;
    private float serverViewTop;
    private float serverViewBottom;
    
    public void SetServerViewRange(float left,float right,float top,float bottom)
    {
        serverViewLeft = left;
        serverViewRight = right;
        serverViewTop = top;
        serverViewBottom = bottom;
    }
    
    public bool CheckPosInServerRect(Vector3 position)
    {
        var rotatedX = position.x * cos45 - position.z * sin45 + WorldEntry.m_mapSize * cos45;
        var rotatedZ = position.x * sin45 + position.z * cos45;
        rotatedX = Mathf.FloorToInt(rotatedX / serverViewGridWidth);
        rotatedZ = Mathf.FloorToInt(rotatedZ / serverViewGridHeight);
        return rotatedX <= serverViewRight && rotatedX >= serverViewLeft && rotatedZ <= serverViewTop &&
               rotatedZ >= serverViewBottom;
    }
    
    private float cos45 = Mathf.Cos(Mathf.PI / 4);
    private float sin45 = Mathf.Sin(Mathf.PI / 4);
    
    private float RotationX(float x,float z)
    {
        float mapSize = WorldEntry.m_mapSize;
        return x * cos45 - z * sin45 + mapSize * cos45;
    }

    private float RotationZ(float x, float z)
    {
        return x * sin45 + z * cos45;
    }

    private float ReverseRotationX(float x, float z)
    {
        float mapSize = WorldEntry.m_mapSize;
        return (x + z - mapSize * cos45) / (2 * cos45);
    }

    private float ReverseRotationZ(float x, float z)
    {
        float mapSize = WorldEntry.m_mapSize;
        return (x - z - mapSize * cos45) / -(2 * cos45);
    }

    private Vector3 GetRotated(float x,float z)
    {
        return new Vector3(RotationX(x, z), 0, RotationZ(x, z));
    }

    private GameObject centerObject;
    
    private void DrawServerViewRect()
    {
#if UNITY_EDITOR
        if (!DebugComponent.GetInstance("Debugger").ShowRangeGrid2)
        {
            return;
        }
        var center = GetRotated(serverViewCenterX, serverViewCenterY);
        var reverseCenter = new Vector3(ReverseRotationX(center.x, center.z), 0, ReverseRotationZ(center.x, center.z));
        var realCenterX = Mathf.FloorToInt(center.x / serverViewGridWidth) * serverViewGridWidth;
        var realCenterY = Mathf.FloorToInt(center.z / serverViewGridHeight) * serverViewGridHeight;
        var q = Quaternion.AngleAxis(45, Vector3.up);
        var realCenter = new Vector3(ReverseRotationX(realCenterX,realCenterY), 0, ReverseRotationZ(realCenterX,realCenterY));
        var realHalfWidth1 = serverViewGridWidth * (serverViewRectWidth / 2 + 1);
        var realHalfWidth2 = serverViewGridWidth * (serverViewRectWidth / 2);
        var realHalfHeight1 = serverViewGridHeight * (serverViewRectHeight / 2 + 1);
        var realHalfHeight2 = serverViewGridHeight * (serverViewRectHeight / 2);
        Color color = Color.yellow;
        
        for (float x = -realHalfWidth2; x <= realHalfWidth1; x += serverViewGridWidth)
        {
            var originStart = q * new Vector3(x, 0, realHalfHeight1) + realCenter;
            var originEnd = q * new Vector3(x, 0, -realHalfHeight2) + realCenter;
            Debug.DrawLine(originStart, originEnd, color,0,false);
        }
        for (float y = -realHalfHeight2; y <= realHalfHeight1; y += serverViewGridHeight)
        {
            var originStart = q * new Vector3(-realHalfWidth2, 0, y) + realCenter;
            var originEnd = q * new Vector3(realHalfWidth1, 0, y) + realCenter;
            Debug.DrawLine(originStart, originEnd, color,0,false);
        }

        /*if (centerObject == null)
        {
            centerObject = GameObject.CreatePrimitive(PrimitiveType.Cube);
        }

        centerObject.transform.position = realCenter;*/
#endif

      
    }

    private void DrawClientEditorViewRect()
    {
#if UNITY_EDITOR
        var Debugger = DebugComponent.GetInstance("Debugger");
        if (!Debugger.ShowRangeGrid)
        {
            return;
        }
        
        var center = GetRotated(serverViewCenterX, serverViewCenterY);
        var reverseCenter = new Vector3(ReverseRotationX(center.x, center.z), 0, ReverseRotationZ(center.x, center.z));
        var realCenterX = Mathf.FloorToInt(center.x / serverViewGridWidth) * serverViewGridWidth;
        var realCenterY = Mathf.FloorToInt(center.z / serverViewGridHeight) * serverViewGridHeight;
        var q = Quaternion.AngleAxis(45, Vector3.up);
        var realCenter = new Vector3(ReverseRotationX(realCenterX, realCenterY), 0, ReverseRotationZ(realCenterX, realCenterY));
        float client_w = Debugger.changeGrid_W_Num + serverViewRectWidth;
        float client_h = Debugger.changeGrid_H_Num + serverViewRectHeight;
        var realHalfWidth1 = serverViewGridWidth * (client_w / 2 + 1);
        var realHalfWidth2 = serverViewGridWidth * (client_w / 2);
        var realHalfHeight1 = serverViewGridHeight * (client_h / 2 + 1);
        var realHalfHeight2 = serverViewGridHeight * (client_h / 2);
        Color color = Color.yellow;

        for (float x = -realHalfWidth2; x <= realHalfWidth1; x += serverViewGridWidth)
        {
            var originStart = q * new Vector3(x, 0, realHalfHeight1) + realCenter;
            var originEnd = q * new Vector3(x, 0, -realHalfHeight2) + realCenter;
            Debug.DrawLine(originStart, originEnd, color, 0, false);
        }
        for (float y = -realHalfHeight2; y <= realHalfHeight1; y += serverViewGridHeight)
        {
            var originStart = q * new Vector3(-realHalfWidth2, 0, y) + realCenter;
            var originEnd = q * new Vector3(realHalfWidth1, 0, y) + realCenter;
            Debug.DrawLine(originStart, originEnd, color, 0, false);
        }

        float lod = DynamicLayerMgr.worldEntry.GetLODLevel();
        float lodPercent = DynamicLayerMgr.worldEntry.GetLODPercent();
        float curH = GetCameraHeight();
        Debug.Log(string.Format("[客户端 沙盘视野] ================== Lod:{0} percent:{1} 当前高度:{2} 格子数量w:{3} h:{4}",
                lod, lodPercent, curH, client_w, client_h));
#endif

    }
}
